package com.glsc.ngateway.flowable.listener.global;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.glsc.ngateway.common.api.flowable.dto.Result;
import com.glsc.ngateway.common.base.domain.mysql.flowable.FlowableCommentSupplement;
import com.glsc.ngateway.flowable.amqp.MessageSender;
import com.glsc.ngateway.flowable.constant.FlowableConstant;
import com.glsc.ngateway.flowable.service.feignservice.AmproductFeignService;
import com.glsc.ngateway.flowable.service.process.FlowableCommentSupplementService;
import com.glsc.ngateway.flowable.util.GatewayExecutionCompensationUtil;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class TaskCompleteListener extends AbstractFlowableEngineEventListener {

    private static Logger logger = LoggerFactory.getLogger(TaskCompleteListener.class);

    @Resource
    private MessageSender sender;

    @Resource
    private AmproductFeignService amproductFeignService;

    @Resource
    private TaskService taskService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private HistoryService historyService;

    @Resource
    private FlowableCommentSupplementService flowableCommentSupplementService;
    @Resource
    GatewayExecutionCompensationUtil util;

    @Override
    protected void taskCompleted(FlowableEngineEntityEvent event) {
        logger.info("进入taskCompleted监听器开始……");
        logger.info("【step】taskCompleted,start");
        TaskEntity task = (TaskEntity) event.getEntity();

        if (StringUtils.isEmpty(task.getParentTaskId())) {
            String msg = "当前节点:" + task.getName() + ", 执行人:" + task.getAssignee() + ", 任务id:" + task.getId() + ", 流程id:" + event.getProcessInstanceId() + ", 执行流id:" + task.getExecutionId();
            logger.info(msg);
            Map<String, Object> existvarmap = runtimeService.getVariables(task.getProcessInstanceId());
            logger.info("processId:" + event.getProcessInstanceId() + ", 已存在的流程变量:" + existvarmap.toString());
//            sender.sendMessage(InitQueue.EXCHANGE, InitQueue.ROUTING_KEY, msg);

            //创建任务前，统一更新设置办理人和条件变量 //"taskAssignee\":{\"userGroup\":\"lm1,lm2\"}
            Map<String, String> taskAssigneeMap = (Map<String, String>) runtimeService.getVariable(task.getProcessInstanceId(), "taskAssignee");
            if (taskAssigneeMap != null) {
                for (Map.Entry<String, String> ass : taskAssigneeMap.entrySet()) {
                    if (!ass.getValue().contains(".")) {
                        String[] g = ass.getValue().split(",");
                        List<String> group = Arrays.stream(g).distinct().collect(Collectors.toList());
                        runtimeService.setVariable(task.getProcessInstanceId(), ass.getKey(), group);
                        runtimeService.setVariable(task.getProcessInstanceId(), ass.getKey() + "Size", group.size());
                    } else {
                        //包含.说明是角色
                        //amprod.role.产品经理
                        String sysid = ass.getValue().split(".")[0];
                        if (sysid.equals(FlowableConstant.AMPROD)) {
                            Result<List<String>> group = amproductFeignService.findAmProductUserIdList(ass.getValue());
                            if (group.getCode() == 10000) {
                                runtimeService.setVariable(task.getProcessInstanceId(), ass.getKey(), group.getData());
                                runtimeService.setVariable(task.getProcessInstanceId(), ass.getKey() + "Size", group.getData().size());
                            } else {
                                logger.error("进入processCreated监听器异常！" + group.toString());
                            }
                        }
                    }
                }
            }

            Map<String, String> conditionMap = (Map<String, String>) runtimeService.getVariable(task.getProcessInstanceId(), "conditionalVariable");
            if (conditionMap != null) {
                for (Map.Entry<String, String> co : conditionMap.entrySet()) {
                    runtimeService.setVariable(task.getProcessInstanceId(), co.getKey(), co.getValue());
                }
            }
        }
        try {
            String processId = "";
            if (StrUtil.isBlank(task.getProcessInstanceId()) && StrUtil.isNotBlank(task.getParentTaskId())) {
                Task parentTask = taskService.createTaskQuery().taskId(task.getParentTaskId()).singleResult();
                processId = parentTask.getProcessInstanceId();
            }
            flowableCommentSupplementService.signTask(task.getId(), processId);
            if (StrUtil.startWith(task.getProcessDefinitionId(), FlowableConstant.AM_PROD_FORWARD_FLOW)) {
                FlowableCommentSupplement fcsRe = new FlowableCommentSupplement();
                Object exProcessId = task.getVariable("exProcessId");
                Object exTaskId = task.getVariable("exTaskId");
                Object userid = task.getVariable("userid");
                Object username = task.getVariable("username");
                Object forwardid = task.getVariable("forwardid");
                Object forwardname = task.getVariable("forwardname");
                HistoricProcessInstance processHis = historyService.createHistoricProcessInstanceQuery().processInstanceId(StrUtil.toString(exProcessId)).singleResult();
                HistoricTaskInstance taskHis = historyService.createHistoricTaskInstanceQuery().processInstanceId(StrUtil.toString(exProcessId)).taskId(StrUtil.toString(exTaskId)).singleResult();
                StringBuilder sb = new StringBuilder();
                sb.append("流程:").append(processHis.getName());
                if (taskHis != null) {
                    sb.append("-节点:").append(taskHis.getName());
                }
                sb.append("-用户:").append(username);
                sb.append(",转发给用户:").append(forwardname);
                List<Comment> taskComments = taskService.getTaskComments(task.getId());
                sb.append("。意见:").append(CollUtil.getFirst(taskComments).getFullMessage());
                if (StrUtil.equals(task.getTaskDefinitionKey(), FlowableConstant.AM_PROD_FORWARD_TASK)) {
                    fcsRe.setTaskAssignee(forwardid.toString());
                } else {
                    fcsRe.setTaskAssignee(userid.toString());
                }
                fcsRe.setTaskId(task.getId());
                fcsRe.setProcessId(StrUtil.toString(exProcessId));
                fcsRe.setTaskName(task.getName());
                fcsRe.setTaskHandleStatus(FlowableConstant.FLOWABLE_TASK_HANDLE_STATUS_SIGN);
                fcsRe.setComment(sb.toString());
                logger.info("进入taskCreated监听器,转发流程备注补充信息:{}", fcsRe);
                flowableCommentSupplementService.save(fcsRe);
            }
        } catch (Exception e) {
            logger.error("进入taskCompleted监听器,流程备注补充信息异常！", e);
        }
        //任务完成时 进行流程网关检测,并自动补偿执行实例
        try {
            String processInstanceId = task.getProcessInstanceId();
            sender.sendMessage(processInstanceId);
//            util.checkAndCompensation(processInstanceId);
//            ThreadUtil.execAsync(() -> {
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException e) {
//                    logger.error("进入taskCompleted监听器,异步检测流程网关异常！", e);
//                }
//                util.checkAndCompensation(processInstanceId);
//            });
            logger.info("进入taskCompleted监听器,检测流程网关");
        } catch (Exception e) {
            logger.error("进入taskCompleted监听器,检测流程网关异常！", e);
        }
        logger.info("【step】taskCompleted,end");
        logger.info("进入taskCompleted监听器结束……");
        //  super.taskCompleted(event);
    }
}